/******************************************************************************中
 * @brief: bsp io
 * @Author:   aple
 * @Date: 2021-06-14 18:06:21
 * @LastEditors: aple
 * @LastEditTime: 2023-03-16 08:31:07
 * @Verision: 1.0.0.0
 ******************************************************************************/
#include "bsp.h"
#include "bsp_io++.h"
#include "iohandle.h"
#include "pincfg.h"
#include "mytype.h"

/*******************************************************************************
 * @brief  gpio struct
 * \param[in] port
 * \param[in] pin
 * \retval: none
 *******************************************************************************/
pin_def_class::pin_def_class(GPIO_TypeDef *port, uint8_t pos)
{
	this->port = port;
	this->pin = 1UL << pos;
	this->pos = pos;
}

/*******************************************************************************
 * @brief  gpio struct init
 * \param[in] port
 * \param[in] pin
 * \retval: none
 *******************************************************************************/
pin_def_class::pin_def_class(GPIO_TypeDef *port, uint8_t pos, uu08 mode)
{
	this->port = port;
	this->pin = 1UL << pos;
	this->pos = pos;
	this->mode(mode);
}

/*******************************************************************************
 * @brief  gpio uninit
 * \param[in] port
 * \param[in] pin
 * \retval: none
 *******************************************************************************/
pin_def_class::~pin_def_class()
{
	this->mode(PIN_MODE_IN_FLOAT);
}

/*******************************************************************************
 * @brief  gpio en
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_def_class::en(void)
{
	this->port->BSRR = this->pin;
}

/*******************************************************************************
 * @brief  gpio dis
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_def_class::dis(void)
{
	this->port->BSRR = this->pin << 16;
}

/*******************************************************************************
 * @brief  gpio tog
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_def_class::tog(void)
{
	if (this->port->ODR & pin)
		this->port->BSRR = this->pin << 16;
	else
		this->port->BSRR = this->pin;
}

/*******************************************************************************
 * @brief  gpio out
 * \param[in] st
 * \retval: none
 *******************************************************************************/
void pin_def_class::out(uu08 st)
{
	if (st)
		this->port->BSRR = this->pin;
	else
		this->port->BSRR = (this->pin << 16);
}

/*******************************************************************************
 * @brief  gpio out st
 * \param[in] none
 * \retval: none
 *******************************************************************************/
uu08 pin_def_class::out_st(void)
{
	uu08 st;

	st = (this->port->ODR & pin) ? 1 : 0;

	return st;
}

/*******************************************************************************
 * @brief  gpio in st
 * \param[in] none
 * \retval: none
 *******************************************************************************/
uu08 pin_def_class::in_st(void)
{
	uu08 st;

	st = (this->port->IDR & pin) ? 1 : 0;

	return st;
}

/*******************************************************************************
 * @brief  gpio struct
 * \param[in] port
 * \param[in] pin
 * \retval: none
 *******************************************************************************/
pin_ndef_class::pin_ndef_class(GPIO_TypeDef *port, uint8_t pos)
{
	this->port = port;
	this->pin = 1UL << pos;
	this->pos = pos;
}

/*******************************************************************************
 * @brief  gpio struct init
 * \param[in] port
 * \param[in] pin
 * \retval: none
 *******************************************************************************/
pin_ndef_class::pin_ndef_class(GPIO_TypeDef *port, uint8_t pos, uu08 mode)
{
	this->port = port;
	this->pin = 1UL << pos;
	this->pos = pos;
	this->mode(mode);
}

/*******************************************************************************
 * @brief  gpio uninit
 * \param[in] port
 * \param[in] pin
 * \retval: none
 *******************************************************************************/
pin_ndef_class::~pin_ndef_class()
{
	this->mode(PIN_MODE_IN_FLOAT);
}

/*******************************************************************************
 * @brief  gpio en
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_ndef_class::en(void)
{
	this->port->BSRR = this->pin << 16;
}

/*******************************************************************************
 * @brief  gpio dis
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_ndef_class::dis(void)
{
	this->port->BSRR = this->pin;
}

/*******************************************************************************
 * @brief  gpio tog
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_ndef_class::tog(void)
{
	if (this->port->ODR & pin)
		this->port->BSRR = this->pin << 16;
	else
		this->port->BSRR = this->pin;
}

/*******************************************************************************
 * @brief  gpio out
 * \param[in] st
 * \retval: none
 *******************************************************************************/
void pin_ndef_class::out(uu08 st)
{
	if (st)
		this->port->BSRR = (this->pin << 16);
	else
		this->port->BSRR = this->pin;
}

/*******************************************************************************
 * @brief  gpio out st
 * \param[in] none
 * \retval: none
 *******************************************************************************/
uu08 pin_ndef_class::out_st(void)
{
	uu08 st;

	st = (this->port->ODR & pin) ? 0 : 1;

	return st;
}

/*******************************************************************************
 * @brief  gpio in st
 * \param[in] none
 * \retval: none
 *******************************************************************************/
uu08 pin_ndef_class::in_st(void)
{
	uu08 st;

	st = (this->port->IDR & pin) ? 0 : 1;

	return st;
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] port pin
 * \retval: none
 *******************************************************************************/
#define micro_mode_out_pp(port, pin)              \
	{                                             \
		intx_alloc();                             \
		intx_disable();                           \
		group_bits2_set(port->MODER, pin, 1UL);   \
		group_bits1_set(port->OTYPER, pin, 0UL);  \
		group_bits2_set(port->OSPEEDR, pin, 2UL); \
		intx_enable();                            \
	}

#define micro_mode_out_od(port, pin)              \
	{                                             \
		intx_alloc();                             \
		intx_disable();                           \
		group_bits2_set(port->MODER, pin, 1UL);   \
		group_bits1_set(port->OTYPER, pin, 1UL);  \
		group_bits2_set(port->OSPEEDR, pin, 2UL); \
		intx_enable();                            \
	}

#define micro_mode_out_pp_spd(port, pin, spd)     \
	{                                             \
		intx_alloc();                             \
		intx_disable();                           \
		group_bits2_set(port->MODER, pin, 1UL);   \
		group_bits1_set(port->OTYPER, pin, 0UL);  \
		group_bits2_set(port->OSPEEDR, pin, spd); \
		intx_enable();                            \
	}

#define micro_mode_out_od_spd(port, pin, spd)     \
	{                                             \
		intx_alloc();                             \
		intx_disable();                           \
		group_bits2_set(port->MODER, pin, 1UL);   \
		group_bits1_set(port->OTYPER, pin, 1UL);  \
		group_bits2_set(port->OSPEEDR, pin, spd); \
		intx_enable();                            \
	}

#define micro_mode_in_up(port, pin)             \
	{                                           \
		intx_alloc();                           \
		intx_disable();                         \
		group_bits2_set(port->MODER, pin, 0UL); \
		group_bits2_set(port->PUPDR, pin, 1UL); \
		intx_enable();                          \
	}

#define micro_mode_in_dn(port, pin)             \
	{                                           \
		intx_alloc();                           \
		intx_disable();                         \
		group_bits2_set(port->MODER, pin, 0UL); \
		group_bits2_set(port->PUPDR, pin, 2UL); \
		intx_enable();                          \
	}

#define micro_mode_in_ft(port, pin)             \
	{                                           \
		intx_alloc();                           \
		intx_disable();                         \
		group_bits2_set(port->MODER, pin, 0UL); \
		group_bits2_set(port->PUPDR, pin, 0UL); \
		intx_enable();                          \
	}

#define micro_mode_ain(port, pin)               \
	{                                           \
		intx_alloc();                           \
		intx_disable();                         \
		group_bits2_set(port->MODER, pin, 3UL); \
		group_bits2_set(port->PUPDR, pin, 0UL); \
		intx_enable();                          \
	}

/*******************************************************************************
 * @brief  IO mode
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_cfg_class::dir_out_pp(void) // 推挽
{
	micro_mode_out_pp(port, pin);
}
void pin_cfg_class::dir_out_od(void) // 开漏
{
	micro_mode_out_od(port, pin);
}
void pin_cfg_class::dir_in_ft(void) // 浮空输入
{
	micro_mode_in_ft(port, pin);
}
void pin_cfg_class::dir_in_up(void) // 上拉输入
{
	micro_mode_in_up(port, pin);
}
void pin_cfg_class::dir_in_dn(void) // 下拉输入
{
	micro_mode_in_dn(port, pin);
}

/*******************************************************************************
 * @brief  gpio mode
 * \param[in] none
 * \retval: none
 *******************************************************************************/
void pin_cfg_class::mode(uu08 mode)
{
	switch (mode)
	{
	case PIN_MODE_IN_UP:
	{
		micro_mode_in_up(port, pin);
		break;
	}
	case PIN_MODE_IN_DN:
	{
		micro_mode_in_dn(port, pin);
		break;
	}
	case PIN_MODE_IN_FLOAT:
	{
		micro_mode_in_ft(port, pin);
		break;
	}
	case PIN_MODE_IN_AIN:
	{
		micro_mode_ain(port, pin);
		break;
	};
	case PIN_MODE_OUT_SL_PP:
	{
		micro_mode_out_pp_spd(port, pin, 0);
		break;
	}
	case PIN_MODE_OUT_SL_OD:
	{
		micro_mode_out_od_spd(port, pin, 0);
		break;
	}
	case PIN_MODE_OUT_SM_PP:
	{
		micro_mode_out_pp_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SM_OD:
	{
		micro_mode_out_od_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SH_PP:
	{
		micro_mode_out_pp_spd(port, pin, 3);
		break;
	}
	case PIN_MODE_OUT_SH_OD:
	{
		micro_mode_out_od_spd(port, pin, 3);
		break;
	}
	default:
	{
		break;
	}
	}
}
